import logging
import os


class StorageAdapter(object):
    """
    This is an abstract class that represents the interface
    that all storage adapters should implement.

    这是一个表示接口的抽象类。
    所有的存储适配器都应该实现。
    """

    def __init__(self, base_query=None, *args, **kwargs):
        """
        Initialize common attributes shared by all storage adapters.
        常见的属性初始化所有存储适配器共享。
        """
        self.kwargs = kwargs
        self.logger = kwargs.get('logger', logging.getLogger(__name__))
        self.adapter_supports_queries = True
        self.base_query = None

    @property
    def Statement(self):
        """
        Create a storage-aware statement.
        创建一个存储感知语句。
        """

        if 'DJANGO_SETTINGS_MODULE' in os.environ:
            django_project = __import__(os.environ['DJANGO_SETTINGS_MODULE'])
            if 'use_django_models' in django_project.settings.CHATTERBOT:
                if django_project.settings.CHATTERBOT['use_django_models'] is True:
                    from django.apps import apps
                    Statement = apps.get_model(django_project.settings.CHATTERBOT['django_app_name'], 'Statement')
                    return Statement

        from chatterbot.conversation.statement import Statement
        statement = Statement
        statement.storage = self
        return statement

    def generate_base_query(self, chatterbot, session_id):
        """
        Create a base query for the storage adapter.
        为存储适配器创建一个基本查询。
        """
        if self.adapter_supports_queries:
            for filter_instance in chatterbot.filters:
                self.base_query = filter_instance.filter_selection(chatterbot, session_id)

    def count(self):
        """
        Return the number of entries in the database.
        返回数据库中的条目数量。
        """
        raise self.AdapterMethodNotImplementedError(
            'The `count` method is not implemented by this adapter.'
        )

    def find(self, statement_text):
        """
        Returns a object from the database if it exists
        返回数据库中的对象是否存在
        """
        raise self.AdapterMethodNotImplementedError(
            'The `find` method is not implemented by this adapter.'
        )

    def remove(self, statement_text):
        """
        Removes the statement that matches the input text.
        Removes any responses from statements where the response text matches
        the input text.

        删除与输入文本匹配的语句。
        从响应文本匹配的语句中删除任何响应。
        输入文本。
        """
        raise self.AdapterMethodNotImplementedError(
            'The `remove` method is not implemented by this adapter.'
        )

    def filter(self, **kwargs):
        """
        Returns a list of objects from the database.
        The kwargs parameter can contain any number
        of attributes. Only objects which contain
        all listed attributes and in which all values
        match for all listed attributes will be returned.
        从数据库返回一个对象列表。
        参数可以包含任意数量的被
        属性。只有包含的对象
        所有列出的属性中的所有值
        对所有列出的属性匹配，将返回。
        """
        raise self.AdapterMethodNotImplementedError(
            'The `filter` method is not implemented by this adapter.'
        )

    def update(self, statement):
        """
        Modifies an entry in the database.
        Creates an entry if one does not exist.
        修改数据库中的条目。
        创建一个不存在的条目
        """
        raise self.AdapterMethodNotImplementedError(
            'The `update` method is not implemented by this adapter.'
        )

    def get_random(self):
        """
        Returns a random statement from the database
        返回从数据库中随机的声明
        """
        raise self.AdapterMethodNotImplementedError(
            'The `get_random` method is not implemented by this adapter.'
        )

    def drop(self):
        """
        Drop the database attached to a given adapter.
        删除连接到给定适配器的数据库。
        """
        raise self.AdapterMethodNotImplementedError(
            'The `drop` method is not implemented by this adapter.'
        )

    def get_response_statements(self):
        """
        Return only statements that are in response to another statement.
        A statement must exist which lists the closest matching statement in the
        in_response_to field. Otherwise, the logic adapter may find a closest
        matching statement that does not have a known response.

        This method may be overridden by a child class to provide more a
        efficient method to get these results.
        只返回对另一语句的响应语句。
        语句必须存在，它列出最接近的匹配语句
        in_response_to场。否则，逻辑适配器可能会找到一个亲密的
        匹配的声明，没有一个已知的响应。
        这种方法可以被类提供更多的孩子
        获得这些结果的有效方法。
        """
        statement_list = self.filter()

        responses = set()
        to_remove = list()
        for statement in statement_list:
            for response in statement.in_response_to:
                responses.add(response.text)
        for statement in statement_list:
            if statement.text not in responses:
                to_remove.append(statement)

        for statement in to_remove:
            statement_list.remove(statement)
        # print('statement_list',statement_list)
        return statement_list

    class EmptyDatabaseException(Exception):

        def __init__(self,
                     value='The database currently contains no entries. At least one entry is expected. You may need to train your chat bot to populate your database.'):
            self.value = value

        def __str__(self):
            return repr(self.value)

    class AdapterMethodNotImplementedError(NotImplementedError):
        """
        An exception to be raised when a storage adapter method has not been implemented.
        Typically this indicates that the method should be implement in a subclass.

        一个例外是当存储适配器方法尚未实施。
        这通常表明该方法应该在子类中实现。
        """
        pass
